home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / rend10.lzh / REND1.0 / GraphicSubSystem / database.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-08  |  8.9 KB  |  318 lines

  1. /*
  2.  * Title:
  3.  *    database.c
  4.  *
  5.  * Authors:
  6.  *    Michael P. Schenck
  7.  *
  8.  * Purpose:
  9.  *    Maintains the storage of all the models and objects used in the 
  10.  *    renderer.  Models can be requested.  Objects although are not
  11.  *    used by the main program directly.  They are allocated when a node
  12.  *    in the displaymap is created which has a model linked to it.  Models
  13.  *    are the schematics of the objects.  Multiple objects can use the same
  14.  *     model for thier design and this can allow the model to be changed
  15.  *    (only position of verticies) to create animation or to morph one
  16.  *    model to another.  Models can be released, but do not need to
  17.  *    be.  When the system is closed, all models will be released anyway.  
  18.  *    When a model is requested, an id is returned specific to the model.
  19.  *    If a model could not be setup, a NOMODEL value is returned.
  20.  *
  21.  * Copyright Info:
  22.  *    Copyright (C) 1993, 1994 -- by Michael P. Schenck, 
  23.  *    (mps4466@ultb.isc.rit.edu)
  24.  *    
  25.  *    This program is free software; you can redistribute it and/or modify
  26.  *    it under the terms of the GNU General Public License as published
  27.  *    by the Free Software Foundation; either version 2 of the License,
  28.  *    or (at your option) any later version.
  29.  *
  30.  *    This software is distributed in the hope that it will be useful, but
  31.  *    WITHOUT ANY WARRANTY; without even the implied warranty of
  32.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  33.  *    GNU General Public License for more details.
  34.  *
  35.  *      For a copy of the GNU General Public License
  36.  *    write to the Free Software Foundation, 675 Mass Ave,
  37.  *    Cambridge, MA  02139, USA.
  38.  *
  39.  */
  40.  
  41. #include <stdlib.h>
  42. #include <stdio.h>
  43. #include <string.h>
  44. #include "/include/types.h"
  45. #include "/include/errors.h"
  46. #include "/include/displaymap.h"
  47. #include "/include/matrix.h"
  48. #include "/include/database.h"
  49.  
  50. struct Model *models[MAXNUMMODELS+1];
  51. struct Object *objects[MAXNUMOBJECTS+1];
  52.  
  53. static UBYTE *linemap = NULL;
  54. static ULONG curlmsize = 0;
  55. static UBYTE modelpath[MAXPATHLEN];
  56. static UBYTE temp[MAXPATHLEN+MAXNAMELEN];
  57. static FILE *fp;
  58.  
  59. ULONG findemptymodelnode(void);
  60. ULONG findmodel(UBYTE *);
  61. ULONG findemptyobjectnode(void);
  62.  
  63.     /* Open the database and set the path to the models. */
  64.  
  65. void opendatabase(UBYTE *path)
  66.  
  67. {
  68.    cleardisplaymap();    
  69.    setdatabasepath(path);
  70. }
  71.  
  72. void setdatabasepath(UBYTE *path)
  73.  
  74. {
  75.    strcpy(modelpath,path);    
  76. }       
  77.  
  78.     /* Find an empty model node in the list. */
  79.  
  80. ULONG findemptymodelnode()
  81.  
  82. {
  83.    ULONG i;
  84.     
  85.    for(i=0;i<MAXNUMMODELS;i++) {    
  86.       if(models[i]==NULL)
  87.          return(i);
  88.    }
  89.    return(NOMODEL);
  90. }        
  91.  
  92.     /* Looks to see if a model has already been loaded into the database. */
  93.  
  94. ULONG findmodel(UBYTE *name)
  95.  
  96. {
  97.    ULONG i;
  98.    
  99.    for(i=0;i<MAXNUMMODELS;i++) {    
  100.       if((models[i]!=NULL)&&(stricmp(models[i]->name,name)==0)&&(models[i]->links!=0))
  101.          return(i);
  102.    }
  103.    return(NOMODEL);
  104. }
  105.     
  106.     /* Requests a model to be loaded into the database. */
  107.     
  108. ULONG requestmodel(UBYTE *name, UBYTE type)
  109.  
  110. {
  111.    ULONG position,numlinks,numvert,numpoly,j,k,offset,firstvert,curvert,nextvert;
  112.    UBYTE *linemaptmp;
  113.        
  114.      
  115.    if(type==SINGLELINK) {
  116.       position=findemptymodelnode();
  117.       numlinks=0;
  118.    }
  119.    else {
  120.       if((position=findmodel(name))!=NOMODEL) {
  121.      models[position]->links++;
  122.      numlinks=models[position]->links;
  123.       }
  124.       else {
  125.      position=findemptymodelnode();
  126.      numlinks=1;
  127.       }
  128.    }         
  129.    if((position!=NOMODEL)&&(numlinks<2)) {       
  130.       strcpy(temp,modelpath);     
  131.       if((fp=fopen(strcat(temp,name),"r"))!=NULL) {
  132.          fread((void *)&numvert,sizeof(ULONG),1,fp);
  133.      fread((void *)&numpoly,sizeof(ULONG),1,fp);
  134.      if((models[position]=(struct Model *)malloc(sizeof(struct Model)))==NULL) {
  135.         fclose(fp);
  136.         models[position]=NULL;
  137.         return(NOMODEL);
  138.      }
  139.          if((models[position]->verticies=(FLOAT *)malloc(4*numvert*sizeof(FLOAT)))==NULL) {
  140.         fclose(fp);
  141.         free((void *)models[position]);
  142.         models[position]=NULL;
  143.         return(NOMODEL);
  144.      }
  145.      if((models[position]->polygons=(ULONG *)malloc(numpoly*MAXPOLYVERT*sizeof(ULONG)))==NULL) {
  146.         fclose(fp);
  147.         free((void *)models[position]->verticies);
  148.         free((void *)models[position]);
  149.         models[position]=NULL;
  150.         return(NOMODEL);
  151.      }
  152.          models[position]->links=numlinks;
  153.      models[position]->numvert=numvert;
  154.      models[position]->numpoly=numpoly;
  155.      strcpy(models[position]->name,name);
  156.      fread((void *)models[position]->verticies,sizeof(FLOAT),4*numvert,fp);
  157.          fread((void *)models[position]->polygons,sizeof(ULONG),numpoly*MAXPOLYVERT,fp);
  158.          fclose(fp);
  159.      if(numvert > curlmsize) {
  160.         if((linemaptmp = (UBYTE *)realloc((void *)linemap,numvert*numvert*sizeof(UBYTE))) == NULL) {
  161.                   free((void *)models[position]->polygons);
  162.            free((void *)models[position]->verticies);
  163.            free((void *)models[position]);
  164.            models[position]=NULL;
  165.            return(NOMODEL);
  166.         }
  167.         linemap = linemaptmp;
  168.         curlmsize = numvert;
  169.      }
  170.      
  171.      for(j=0;j<curlmsize*curlmsize;j++)
  172.         *(linemap+j) = FALSE;
  173.  
  174.      if((models[position]->edgeshare=(UBYTE *)malloc(numpoly*MAXPOLYVERT*sizeof(UBYTE)))==NULL) {
  175.         free((void *)models[position]->polygons);
  176.         free((void *)models[position]->verticies);
  177.         free((void *)models[position]);
  178.         models[position]=NULL;
  179.         return(NOMODEL);
  180.      }
  181.      
  182.      for(j=0;j<numpoly*MAXPOLYVERT;j++)
  183.         *(models[position]->edgeshare+j) = TRUE;
  184.              
  185.      for(j=0;j<numpoly*MAXPOLYVERT;j+=MAXPOLYVERT) {
  186.         firstvert = *(models[position]->polygons+j);
  187.         curvert = firstvert;
  188.         for(k=1;k<(MAXPOLYVERT-1);k++) {
  189.            offset = k;
  190.            if((nextvert = *(models[position]->polygons+j+k))==NOVERT) {
  191.               k=MAXPOLYVERT-1;
  192.               nextvert = firstvert;
  193.            }
  194.            if(*(linemap+curvert*curlmsize+nextvert) == FALSE) {
  195.                  *(linemap+curvert*curlmsize+nextvert) = TRUE;
  196.           *(linemap+nextvert*curlmsize+curvert) = TRUE;
  197.            }
  198.            else
  199.               *(models[position]->edgeshare+j+offset-1) = FALSE;
  200.            curvert = nextvert;
  201.         }
  202.      }
  203.       }
  204.       else
  205.      position=NOMODEL;
  206.    }
  207.    return(position);      
  208. }           
  209.  
  210.      /* Releases the model specified.  If there is more than one link,
  211.        it decrements the link by one. */
  212.  
  213. void releasemodel(ULONG model)
  214.  
  215. {
  216.    if(models[model]->links>1)
  217.       models[model]->links--;
  218.    else {
  219.       free((void *)models[model]->edgeshare);
  220.       free((void *)models[model]->verticies);
  221.       free((void *)models[model]->polygons);
  222.       free((void *)models[model]);
  223.       models[model]=NULL;
  224.    }                 
  225. }       
  226.  
  227.     /* Finds an available object node. */
  228.  
  229. ULONG findemptyobjectnode()
  230.  
  231. {
  232.    ULONG i;
  233.     
  234.    for(i=0;i<MAXNUMOBJECTS;i++) {    
  235.       if(objects[i]==NULL)
  236.          return(i);
  237.    }
  238.    return(NOOBJECT);
  239. }        
  240.  
  241.     /* Allocates space for an object and links to an object node. */
  242.  
  243. ULONG allocateobject(ULONG model) 
  244.  
  245.    ULONG i,position;    
  246.     
  247.    if((position=findemptyobjectnode())==NOOBJECT)
  248.       return(NOOBJECT);
  249.    if((objects[position]=(struct Object *)malloc(sizeof(struct Object)))==NULL)
  250.       return(NOOBJECT);
  251.    if((objects[position]->verticies=(FLOAT *)malloc(4*models[model]->numvert*sizeof(FLOAT)))==NULL) {
  252.       free((void *)objects[position]);
  253.       objects[position]=NULL;
  254.       return(NOOBJECT);
  255.    }    
  256.    if((objects[position]->transvert=(FLOAT *)malloc(4*models[model]->numvert*sizeof(FLOAT)))==NULL) {
  257.       free((void *)objects[position]->verticies);
  258.       free((void *)objects[position]);
  259.       objects[position]=NULL;
  260.       return(NOOBJECT);
  261.    }    
  262.    if((objects[position]->vertflag=(UBYTE *)malloc(models[model]->numvert*sizeof(UBYTE)))==NULL) {
  263.       free((void *)objects[position]->verticies);
  264.       free((void *)objects[position]->transvert);
  265.       free((void *)objects[position]);
  266.       objects[position]=NULL;
  267.       return(NOOBJECT);
  268.    }
  269.    if((objects[position]->polygons=(ULONG *)malloc(models[model]->numpoly*MAXPOLYVERT*sizeof(ULONG)))==NULL) {
  270.       free((void *)objects[position]->verticies);
  271.       free((void *)objects[position]->transvert);
  272.       free((void *)objects[position]->vertflag);
  273.       free((void *)objects[position]);
  274.       objects[position]=NULL;
  275.       return(NOOBJECT);
  276.    }
  277.    for(i=0;i<models[model]->numpoly*MAXPOLYVERT;i++)
  278.       *(objects[position]->polygons+i) = *(models[model]->polygons+i);
  279.    objects[position]->numvert = models[model]->numvert;
  280.    objects[position]->numpoly = models[model]->numpoly;
  281.    objects[position]->edgeshare = models[model]->edgeshare;
  282.    return(position);  
  283. }
  284.     
  285.     /* Deallocates an object. */
  286.     
  287. void deallocateobject(ULONG object)
  288.  
  289. {  
  290.    free((void *)objects[object]->verticies);
  291.    free((void *)objects[object]->transvert);
  292.    free((void *)objects[object]->vertflag);  
  293.    free((void *)objects[object]->polygons);
  294.    free((void *)objects[object]);
  295.    objects[object]=NULL;        
  296. }        
  297.  
  298.      /* Closes down the database, releasing all models and objects. */
  299.  
  300. void closedatabase()
  301.  
  302. {
  303.    ULONG i;
  304.     
  305.    cleardisplaymap();
  306.    for(i=0;i<MAXNUMMODELS;i++) {
  307.       if(models[i]!=NULL)
  308.          releasemodel(i);
  309.    }
  310.    for(i=0;i<MAXNUMOBJECTS;i++) {
  311.       if(objects[i]!=NULL)
  312.          deallocateobject(i);
  313.    }
  314.    if(linemap)
  315.       free((void *)linemap);
  316. }
  317.